home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / ideas / track.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  25KB  |  1,044 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1995. */
  3.  
  4. /*
  5.  * (c) Copyright 1993, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40. #include <math.h>
  41. #include <sys/time.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include "objects.h"
  45. #include <GL/glut.h>
  46.  
  47. #define X 0
  48. #define Y 1
  49. #define Z 2
  50.  
  51. #ifndef TRUE
  52. #define TRUE 1
  53. #endif
  54. #ifndef FALSE
  55. #define FALSE 0
  56. #endif
  57.  
  58. #define DEG *M_PI/180.0
  59. #define RAD *180.0/M_PI
  60.  
  61. float move_speed;        /* Spline distance per second */
  62.  
  63. int multisample = 0;        /* Antialias polygons? */
  64. int doublebuffer = 1;        /* Doublebuffer? */
  65.  
  66.  
  67. #define SPEED_SLOW        0.2    /* Spline distances per second */
  68. #define SPEED_MEDIUM        0.4
  69. #define SPEED_FAST        0.7
  70. #define SPEED_SUPER_FAST    1.0
  71.  
  72. #define O_NOMS        7
  73. #define O_4MS        8
  74. #define O_8MS        9
  75. #define O_16MS        10
  76.  
  77. static int RGBA_SB_attributes = GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH;
  78.  
  79. static int RGBA_SB_ST_attributes = GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STEREO;
  80.  
  81. static int RGBA_DB_attributes = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
  82.  
  83. static int RGBA_DB_ST_attributes = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STEREO;
  84.  
  85. float idmat[4][4] = {
  86.     {1.0, 0.0, 0.0, 0.0},
  87.     {0.0, 1.0, 0.0, 0.0},
  88.     {0.0, 0.0, 1.0, 0.0},
  89.     {0.0, 0.0, 0.0, 1.0},
  90. };
  91.  
  92. float light1_ambient[] = { 0.0,0.0,0.0,1.0 };
  93. float light1_lcolor[] = { 1.0,1.0,1.0,1.0 };
  94. float light1_position[] = { 0.0,1.0,0.0,0.0 };
  95.  
  96. float light2_ambient[] = { 0.0,0.0,0.0,1.0 };
  97. float light2_lcolor[] = { 0.3,0.3,0.5,1.0 };
  98. float light2_position[] = { -1.0,0.0,0.0,0.0 };
  99.  
  100. float light3_ambient[] = { 0.2,0.2,0.2,1.0 };
  101. float light3_lcolor[] = { 0.2,0.2,0.2,1.0 };
  102. float light3_position[] = { 0.0,-1.0,0.0,0.0 };
  103.  
  104. float lmodel_LVW[] = { 0.0 };
  105. float lmodel_ambient[] = { 0.3,0.3,0.3,1.0 };
  106. float lmodel_TWO[] = { GL_TRUE };
  107.  
  108. float mat_logo_ambient[] = {0.1, 0.1, 0.1, 1.0};
  109. float mat_logo_diffuse[] = {0.5, 0.4, 0.7, 1.0};
  110. float mat_logo_specular[] = {1.0, 1.0, 1.0, 1.0};
  111. float mat_logo_shininess[] = {30.0};
  112.  
  113. float mat_holder_base_ambient[] = {0.0, 0.0, 0.0, 1.0};
  114. float mat_holder_base_diffuse[] = {0.6, 0.6, 0.6, 1.0};
  115. float mat_holder_base_specular[] = {0.8, 0.8, 0.8, 1.0};
  116. float mat_holder_base_shininess[] = {30.0};
  117.  
  118. float mat_holder_rings_ambient[] = { 0.0,0.0,0.0,1.0 };
  119. float mat_holder_rings_diffuse[] = { 0.9,0.8,0.0,1.0 };
  120. float mat_holder_rings_specular[] = { 1.0,1.0,1.0,1.0 };
  121. float mat_holder_rings_shininess[] = { 30.0 };
  122.  
  123. float mat_hemisphere_ambient[] = {0.0, 0.0, 0.0,1.0 };
  124. float mat_hemisphere_diffuse[] = {1.0, 0.2, 0.2,1.0 };
  125. float mat_hemisphere_specular[] = {0.5, 0.5, 0.5,1.0 };
  126. float mat_hemisphere_shininess[] = {20.0};
  127.  
  128. GLubyte stipple[32*32];
  129.  
  130. typedef float vector[3];
  131. typedef vector parameter[4];
  132.  
  133. /*
  134.  * Function definitions
  135.  */
  136. void initialize(void);
  137. void resize_window(int w, int h);
  138. void build_table(void);
  139. parameter *calc_spline_params(vector *ctl_pts, int n);
  140. void calc_spline(vector v, parameter *params, float current_time);
  141. void normalize(vector v);
  142. float dot(vector v1, vector v2);
  143. void draw_table(void);
  144. void draw_logo_shadow(void);
  145. void draw_hemisphere(void);
  146. void draw_logo(void);
  147. void draw_under_table(void);
  148. void draw_i(void);
  149. void draw_d(void);
  150. void draw_e(void);
  151. void draw_a(void);
  152. void draw_s(void);
  153. void draw_n(void);
  154. void draw_m(void);
  155. void draw_o(void);
  156. void draw_t(void);
  157.  
  158. int post_idle = 0;
  159. void idle(void);
  160. void do_post_idle(void);
  161. void display(void);
  162. void mouse(int b, int s, int x, int y);
  163. void keyboard(unsigned char c, int x, int y);
  164. void vis(int);
  165.  
  166. void init_materials(void) {
  167.   int x, y;
  168.  
  169.   /* Stipple pattern */
  170.   for (y = 0; y < 32; y++)
  171.     for (x = 0; x < 4; x++) 
  172.       stipple[y * 4 + x] = (y % 2) ? 0xaa : 0x55;
  173.  
  174.     glNewList(MAT_LOGO, GL_COMPILE); 
  175.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_logo_ambient); 
  176.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_logo_diffuse);
  177.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_logo_specular);
  178.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_logo_shininess);
  179.     glEndList(); 
  180.  
  181.     glNewList( MAT_HOLDER_BASE, GL_COMPILE);
  182.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_base_ambient); 
  183.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_base_diffuse);
  184.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_base_specular);
  185.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_base_shininess);
  186.     glEndList();
  187.  
  188.     glNewList(MAT_HOLDER_RINGS, GL_COMPILE); 
  189.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_rings_ambient); 
  190.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_rings_diffuse);
  191.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_rings_specular);
  192.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_rings_shininess);
  193.     glEndList();
  194.  
  195.     glNewList(MAT_HEMISPHERE, GL_COMPILE); 
  196.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_hemisphere_ambient); 
  197.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_hemisphere_diffuse);
  198.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_hemisphere_specular);
  199.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_hemisphere_shininess);
  200.     glEndList();
  201.  
  202. }
  203.  
  204. void init_lights(void) {
  205.   static float ambient[] = { 0.1, 0.1, 0.1, 1.0 };
  206.   static float diffuse[] = { 0.5, 1.0, 1.0, 1.0 };
  207.   static float position[] = { 90.0, 90.0, 150.0, 0.0 };
  208.   
  209.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  210.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  211.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  212.  
  213.   glLightfv (GL_LIGHT1, GL_AMBIENT, light1_ambient);
  214.   glLightfv (GL_LIGHT1, GL_SPECULAR, light1_lcolor);
  215.   glLightfv (GL_LIGHT1, GL_DIFFUSE, light1_lcolor);
  216.   glLightfv (GL_LIGHT1, GL_POSITION, light1_position);
  217.     
  218.   glLightfv (GL_LIGHT2, GL_AMBIENT, light2_ambient);
  219.   glLightfv (GL_LIGHT2, GL_SPECULAR, light2_lcolor);
  220.   glLightfv (GL_LIGHT2, GL_DIFFUSE, light2_lcolor);
  221.   glLightfv (GL_LIGHT2, GL_POSITION, light2_position);
  222.  
  223.   glLightfv (GL_LIGHT3, GL_AMBIENT, light3_ambient);
  224.   glLightfv (GL_LIGHT3, GL_SPECULAR, light3_lcolor);
  225.   glLightfv (GL_LIGHT3, GL_DIFFUSE, light3_lcolor);
  226.   glLightfv (GL_LIGHT3, GL_POSITION, light3_position);
  227.   
  228.   glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_LVW);
  229.   glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  230. }
  231.  
  232. short dev, val;
  233.  
  234. float current_time=0.0;
  235. float hold_time=0.0;        /* Used when auto-running */
  236.  
  237. float tmplight[] = {
  238.     GL_POSITION, 0.0, 0.0, 0.0, 0.0, 
  239. };
  240.  
  241. GLfloat tv[4][4] = {
  242.   {1.0, 0.0, 0.0, 0.0},
  243.   {0.0, 1.0, 0.0, -1.0},
  244.   {0.0, 0.0, 1.0, 0.0},
  245.   {0.0, 0.0, 0.0, 0.0},
  246. };
  247.  
  248. #define TABLERES 12
  249.  
  250. float pcr, pcg, pcb, pca;
  251.  
  252. vector table_points[TABLERES+1][TABLERES+1];
  253. int tablecolors[TABLERES+1][TABLERES+1];
  254.  
  255. vector paper_points[4] = {
  256.     {-0.8, 0.0, 0.4},
  257.     {-0.2, 0.0, -1.4},
  258.     {1.0, 0.0, -1.0},
  259.     {0.4, 0.0, 0.8},
  260. };
  261.  
  262. float dot(vector, vector);
  263.  
  264. #define TIME 15
  265. #define START_TIME 0.6
  266.  
  267. vector light_pos_ctl[] = {
  268.  
  269.     {0.0, 1.8, 0.0},
  270.     {0.0, 1.8, 0.0},
  271.     {0.0, 1.6, 0.0},
  272.  
  273.     {0.0, 1.6, 0.0},
  274.     {0.0, 1.6, 0.0},
  275.     {0.0, 1.6, 0.0},
  276.     {0.0, 1.4, 0.0},
  277.  
  278.     {0.0, 1.3, 0.0},
  279.     {-0.2, 1.5, 2.0},
  280.     {0.8, 1.5, -0.4},
  281.     {-0.8, 1.5, -0.4},
  282.  
  283.     {0.8, 2.0, 1.0},
  284.     {1.8, 5.0, -1.8},
  285.     {8.0, 10.0, -4.0},
  286.     {8.0, 10.0, -4.0},
  287.     {8.0, 10.0, -4.0},
  288. };
  289.  
  290. vector logo_pos_ctl[] = {
  291.  
  292.     {0.0, -0.5, 0.0},
  293.  
  294.     {0.0, -0.5, 0.0},
  295.     {0.0, -0.5, 0.0},
  296.  
  297.     {0.0, -0.5, 0.0},
  298.     {0.0, -0.5, 0.0},
  299.     {0.0, -0.5, 0.0},
  300.     {0.0, 0.0, 0.0},
  301.  
  302.     {0.0, 0.6, 0.0},
  303.     {0.0, 0.75, 0.0},
  304.     {0.0, 0.8, 0.0},
  305.     {0.0, 0.8, 0.0},
  306.  
  307.     {0.0, 0.5, 0.0},
  308.     {0.0, 0.5, 0.0},
  309.     {0.0, 0.5, 0.0},
  310.     {0.0, 0.5, 0.0},
  311.     {0.0, 0.5, 0.0},
  312. };
  313.  
  314.  
  315. vector logo_rot_ctl[] = {
  316.  
  317.     {0.0, 0.0, -18.4},
  318.  
  319.     {0.0, 0.0, -18.4},
  320.     {0.0, 0.0, -18.4},
  321.  
  322.     {0.0, 0.0, -18.4},
  323.     {0.0, 0.0, -18.4},
  324.     {0.0, 0.0, -18.4},
  325.     {0.0, 0.0, -18.4},
  326.     {0.0, 0.0, -18.4},
  327.  
  328. /*    {90.0, 0.0, -90.0},
  329.     {180.0, 180.0, 90.0}, */
  330.     {240.0, 360.0, 180.0},
  331.     {90.0, 180.0, 90.0},
  332.  
  333.     {11.9, 0.0, -18.4},
  334.     {11.9, 0.0, -18.4},
  335.     {11.9, 0.0, -18.4},
  336.     {11.9, 0.0, -18.4},
  337.     {11.9, 0.0, -18.4},
  338. };
  339.  
  340.  
  341. vector view_from_ctl[] = {
  342.  
  343.     {-1.0, 1.0, -4.0},
  344.  
  345.     {-1.0, -3.0, -4.0},    /* 0 */
  346.     {-3.0, 1.0, -3.0},    /* 1 */
  347.  
  348.     {-1.8, 2.0, 5.4},    /* 2 */
  349.     {-0.4, 2.0, 1.2},    /* 3 */
  350.     {-0.2, 1.5, 0.6},    /* 4 */
  351.     {-0.2, 1.2, 0.6},    /* 5 */
  352.  
  353.     {-0.8, 1.0, 2.4},    /* 6 */
  354.     {-1.0, 2.0, 3.0},    /* 7 */
  355.     {0.0, 4.0, 3.6},    /* 8 */
  356.     {-0.8, 4.0, 1.2},    /* 9 */
  357.  
  358.     {-0.2, 3.0, 0.6},    /* 10 */
  359.     {-0.1, 2.0, 0.3},    /* 11 */
  360.     {-0.1, 2.0, 0.3},    /* 12 */
  361.     {-0.1, 2.0, 0.3},    /* 13 */
  362.     {-0.1, 2.0, 0.3},    /* 13 */
  363.  
  364.  
  365. };
  366.  
  367. vector view_to_ctl[] = {
  368.  
  369.     {-1.0, 1.0, 0.0},
  370.  
  371.     {-1.0, -3.0, 0.0},
  372.     {-1.0, 1.0, 0.0},
  373.  
  374.     {0.1, 0.0, -0.3},
  375.     {0.1, 0.0, -0.3},
  376.     {0.1, 0.0, -0.3},
  377.     {0.0, 0.2, 0.0},
  378.  
  379.     {0.0, 0.6, 0.0},
  380.     {0.0, 0.8, 0.0},
  381.     {0.0, 0.8, 0.0},
  382.     {0.0, 0.8, 0.0},
  383.  
  384.     {0.0, 0.8, 0.0},
  385.     {0.0, 0.8, 0.0},
  386.     {0.0, 0.8, 0.0},
  387.     {0.0, 0.8, 0.0},
  388.     {0.0, 0.8, 0.0},
  389.  
  390. };
  391.  
  392.  
  393. vector view_from, view_to, light_pos, logo_pos, logo_rot;
  394.  
  395. parameter *view_from_spline, *view_to_spline,
  396.       *light_pos_spline, *logo_pos_spline,
  397.       *logo_rot_spline;
  398.  
  399. parameter *calc_spline_params(vector *, int);
  400.  
  401. double a3, a4;
  402.  
  403. void ideas_usage(void)
  404. {
  405.   fprintf(stderr, "Usage: ideas [-a] [-m] [-d] -s{1-4}\n");
  406.   fprintf(stderr, "Press ESC to quit, 1-4 to control speed, any other key\n");
  407.   fprintf(stderr, "to pause.\n");
  408. }
  409.  
  410.   int auto_run;        /* If set, then automatically run forever */
  411.   float new_speed;    /* Set new animation speed? */
  412.   int timejerk;        /* Set to indicate time jerked! (menu pulled down) */
  413.   int paused = 0;    /* Paused? */
  414.   int right = 0;    /* Draw right eye? */
  415.   int resetclock;    /* Reset the clock? */
  416.   float timeoffset;    /* Used to compute timing */
  417.   struct timeval start;
  418.  
  419. void main(int argc, char **argv)
  420. {
  421.   int i;
  422.  
  423.   glutInit(&argc, argv);
  424.  
  425.   auto_run = 0;    /* Don't automatically run forever */
  426.   /* .4 spline distance per second by default */
  427.   move_speed = SPEED_MEDIUM;
  428.   new_speed = SPEED_MEDIUM;
  429.   timeoffset = START_TIME;
  430.   
  431.   for (i = 1; i < argc; i++) {
  432.     if (argv[i][0] != '-') {
  433.       break;
  434.     }
  435.     
  436.     switch(argv[i][1]) {
  437.     case 'a':    /* Keep running forever */
  438.       auto_run = 1;
  439.       break;
  440.     case 'm':    /* Multisample */
  441.       multisample = 1;
  442.       break;
  443.     case 'd':    /* Single buffer */
  444.       doublebuffer = 0;
  445.       break;
  446.     case 's':
  447.       switch(argv[i][2]) {
  448.       case '1':
  449.     move_speed = new_speed = SPEED_SLOW;
  450.     break;
  451.       case '2':
  452.     move_speed = new_speed = SPEED_MEDIUM;
  453.     break;
  454.       case '3':
  455.     move_speed = new_speed = SPEED_FAST;
  456.     break;
  457.       case '4':
  458.     move_speed = new_speed = SPEED_SUPER_FAST;
  459.     break;
  460.       }
  461.       break;
  462.     default:
  463.       ideas_usage();
  464.       break;
  465.     }
  466.   }
  467.   
  468.   initialize();
  469.   
  470.   current_time = timeoffset;
  471.   resetclock = 1;
  472.   timejerk = 0;
  473.   glutMainLoop();
  474. }
  475.  
  476. void idle(void) 
  477. {
  478.     if ((current_time) > (TIME*1.0)-3.0) {
  479.       if (auto_run) {
  480.     hold_time += current_time - (TIME - 3.001);
  481.     if (hold_time > 3.0) {    /* 3 second hold */
  482.       hold_time = 0.0;
  483.       resetclock = 1;
  484.     }
  485.       } else {
  486.         if(!resetclock) glutIdleFunc(NULL);
  487.       }
  488.       current_time = (TIME*1.0)-3.001;
  489.     } else {
  490.        post_idle = 1;
  491.     }
  492.     glutPostRedisplay();
  493. }
  494.  
  495. void
  496. mouse(int b, int s, int x, int y)
  497. {
  498.    if(b == GLUT_LEFT_BUTTON && s == GLUT_DOWN) {
  499.       resetclock = 1;
  500.       paused = 0;
  501.       glutIdleFunc(idle);
  502.    }
  503. }
  504.  
  505. void
  506. keyboard(unsigned char c, int x, int y)
  507. {
  508.    switch(c) {
  509.    case 27:
  510.       exit(0);
  511.       break;
  512.    case '1':
  513.       new_speed = SPEED_SLOW;
  514.       break;
  515.    case '2':
  516.       new_speed = SPEED_MEDIUM;
  517.       break;
  518.    case '3':
  519.       new_speed = SPEED_FAST;
  520.       break;
  521.    case '4':
  522.       new_speed = SPEED_SUPER_FAST;
  523.       break;
  524.    default:
  525.       if (paused) timejerk = 1;
  526.       paused = ~paused;
  527.       if(paused) {
  528.      glutIdleFunc(NULL);
  529.       } else {
  530.      glutIdleFunc(idle);
  531.       }
  532.    }
  533. }
  534.  
  535. void
  536. vis(int visible)
  537. {
  538.   if (visible == GLUT_VISIBLE) {
  539.       if(!paused) glutIdleFunc(idle);
  540.       do_post_idle();
  541.   } else {
  542.       if(!paused) glutIdleFunc(NULL);
  543.   }
  544. }
  545.  
  546. void display(void)
  547. {
  548.   float x, y, z, c;
  549.  
  550.     calc_spline(view_from, view_from_spline, current_time);
  551.     calc_spline(view_to, view_to_spline, current_time);
  552.     calc_spline(light_pos, light_pos_spline, current_time);
  553.     calc_spline(logo_pos, logo_pos_spline, current_time);
  554.     calc_spline(logo_rot, logo_rot_spline, current_time);
  555.     
  556.     tmplight[1] = light_pos[X] - logo_pos[X];
  557.     tmplight[2] = light_pos[Y] - logo_pos[Y];
  558.     tmplight[3] = light_pos[Z] - logo_pos[Z];
  559.     
  560.     glNewList(LIGHT_TMP, GL_COMPILE); 
  561.     glMaterialf(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, * tmplight); 
  562.     glEndList();
  563.     
  564.     tv[0][0] = tv[1][1] = tv[2][2] = light_pos[Y];
  565.     
  566.     glColor3ub(0,  0,  0);
  567.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
  568.     
  569.     /*
  570.      * SHADOW
  571.      */
  572.     glMatrixMode(GL_MODELVIEW);
  573.     glLoadIdentity();
  574.     gluLookAt(view_from[X], view_from[Y], view_from[Z], 
  575.           view_to[X], view_to[Y], view_to[Z],
  576.           0.0, 1.0, 0.0);
  577.     
  578.     if (view_from[Y] > 0.0) draw_table();
  579.  
  580.     glEnable(GL_CULL_FACE); 
  581.     glDisable(GL_DEPTH_TEST); 
  582.  
  583.     if (logo_pos[Y] < 0.0) {
  584.       
  585.       if (logo_pos[Y]>-0.33) {
  586.     /* We're emerging from the table */
  587.     c = 1.0 - (logo_pos[Y]) / -0.33;
  588.     pca /= 4.0;
  589.     glColor3ub((int)(128.0*(1.0-c)*0.5 + 255.0*pca*c),
  590.            (int)(102.0*(1.0-c)*0.5 + 255.0*pca*c),
  591.            (int)(179.0*(1.0-c)*0.5 + 200.0*pca*c));
  592.       } else {
  593.     /* Still under table */
  594.     glColor3ub(128/2,  102/2,  179/2);
  595.       }
  596.       
  597.       glPushMatrix();
  598.       glScalef(0.04,  0.0,  0.04);
  599.       glRotatef(0.1 * (-900), 1.0, 0.0, 0.0);
  600.       glRotatef(0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  601.       glRotatef(0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  602.       glRotatef(0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  603.       glRotatef(0.1 * (353), 1.0, 0.0, 0.0);
  604.       glRotatef(0.1 * (450), 0.0, 1.0, 0.0);
  605.       draw_logo_shadow();
  606.       glPopMatrix();
  607.     }
  608.     
  609.     if (logo_pos[Y] > 0.0) {
  610.       glPushMatrix();
  611.       if (logo_pos[Y]<0.33) {
  612.     pca /= 4.0;
  613.     c = 1.0 - (logo_pos[Y])/0.33;
  614.     glColor3ub((int)(255.0*pca*c),
  615.            (int)(255.0*pca*c),
  616.            (int)(200.0*pca*c));
  617.       } else {
  618.     glColor3ub(0, 0, 0);
  619.       }
  620.       
  621.       glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  622.       glMultMatrixf(&tv[0][0]);
  623.       glTranslatef(-light_pos[X]+logo_pos[X],
  624.            -light_pos[Y]+logo_pos[Y],
  625.            -light_pos[Z]+logo_pos[Z]);
  626.       glScalef(0.04,  0.04,  0.04);
  627.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  628.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  629.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  630.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  631.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  632.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  633.  
  634.  
  635.       glEnable(GL_POLYGON_STIPPLE);
  636.       glPolygonStipple(stipple);
  637.       draw_logo_shadow();
  638.       glDisable(GL_POLYGON_STIPPLE);
  639.       glPopMatrix();
  640.     }
  641.     /*
  642.      * DONE SHADOW 
  643.      */
  644.  
  645.  
  646.     glEnable(GL_DEPTH_TEST);
  647.     glDisable(GL_CULL_FACE);
  648.     glEnable(GL_LIGHTING);
  649.  
  650.     glMatrixMode(GL_PROJECTION);
  651.     glLoadIdentity();
  652.     gluPerspective(.1*(450),  5.0/4.0,  0.5,  20.0);
  653.     glMatrixMode(GL_MODELVIEW);
  654.     glLoadMatrixf(&idmat[0][0]); 
  655.     
  656.     gluLookAt(view_from[X],  view_from[Y],  view_from[Z],
  657.           view_to[X],  view_to[Y],  view_to[Z], 
  658.           0.0, 1.0, 0.0);
  659.     
  660.     glCallList( MAT_HOLDER_RINGS); 
  661.     
  662.     glPushMatrix();
  663.     glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  664.     glScalef(0.1,  0.1,  0.1);
  665.     
  666.     x = light_pos[X] - logo_pos[X];
  667.     y = light_pos[Y] - logo_pos[Y];
  668.     z = light_pos[Z] - logo_pos[Z];
  669.     
  670.     if (x!=0.0) {
  671.       a3 = -atan2(z, x)*10.0 RAD;
  672.     } else a3 = 0.0;
  673.     
  674.     a4 = -atan2(sqrt(x*x + z*z), y)*10.0 RAD;
  675.     
  676.     glRotatef (0.1 * ((int)a3), 0.0, 1.0, 0.0);
  677.     glRotatef (0.1 * ((int)a4), 0.0, 0.0, 1.0);
  678.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  679.     
  680.     glEnable(GL_LIGHT2);
  681.     glEnable(GL_LIGHT3);
  682.     glCallList(MAT_HEMISPHERE);
  683.     glEnable(GL_NORMALIZE);
  684.     draw_hemisphere();
  685.     glDisable(GL_NORMALIZE);
  686.     glPopMatrix();
  687.  
  688.     glDisable(GL_LIGHT2);
  689.     glDisable(GL_LIGHT3); 
  690.     glEnable(GL_LIGHT1);
  691.     glLightfv(GL_LIGHT1, GL_POSITION, light_pos);
  692.     
  693.     if (logo_pos[Y] > -0.33) {
  694.  
  695.       glCallList(MAT_LOGO);
  696.     
  697.       glPushMatrix();
  698.       glTranslatef(logo_pos[X],  logo_pos[Y],  logo_pos[Z]);
  699.       glScalef(0.04,  0.04,  0.04);
  700.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  701.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  702.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  703.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  704.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  705.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  706.       glEnable(GL_LIGHTING);
  707.       draw_logo();
  708.       glPopMatrix();
  709.     }
  710.     
  711.     if (view_from[Y] < 0.0) draw_under_table();
  712.     
  713.     glutSwapBuffers();
  714.  
  715.     if(post_idle) do_post_idle();
  716. }
  717.  
  718. void do_post_idle(void)
  719. {
  720.   struct timeval current;
  721.   float timediff;    
  722.  
  723.     /* Time jerked -- adjust clock appropriately */
  724.     if (timejerk) {
  725.       timejerk = 0;
  726.       timeoffset = current_time;
  727.       gettimeofday(&start, NULL);
  728.     }
  729.     
  730.     /* Reset our timer */
  731.     if (resetclock) {
  732.       resetclock = 0;
  733.       paused = 0;
  734.       timeoffset = START_TIME;
  735.       gettimeofday(&start, NULL);
  736.     }
  737.     
  738.     /* Compute new time */
  739.     gettimeofday(¤t, NULL);
  740.     timediff = (current.tv_sec - start.tv_sec) + 
  741.       (current.tv_usec - start.tv_usec) / 1000000.0;
  742.     if (!paused) {
  743.        current_time = timediff * move_speed + timeoffset;
  744.     }
  745.     
  746.     /* Adjust to new speed */
  747.     if (new_speed != move_speed) {
  748.       move_speed = new_speed;
  749.       timeoffset = current_time;
  750.       gettimeofday(&start, NULL);
  751.     }
  752.     post_idle = 0;
  753. }
  754.  
  755. void resize_window(int w, int h) 
  756. {
  757.   glMatrixMode(GL_PROJECTION);
  758.   glLoadIdentity();
  759.   gluPerspective (45.0, 5.0/4.0, 0.5, 20.0); 
  760.   glMatrixMode(GL_MODELVIEW);
  761.   glLoadIdentity();
  762.   glViewport(0, 0, w, h);
  763. }
  764.  
  765. void initialize(void)
  766. {
  767.     int attr;
  768.  
  769.     attr = doublebuffer ? RGBA_DB_attributes : RGBA_SB_attributes;
  770.     glutInitDisplayMode(attr);
  771.     glutInitWindowSize(300, 240);
  772.     glutCreateWindow("Ideas");
  773.  
  774.     if (multisample) glEnable(GL_POLYGON_SMOOTH); 
  775.     
  776.     init_lights();
  777.     init_materials();
  778.  
  779.     build_table();
  780.  
  781.     view_from_spline = calc_spline_params(view_from_ctl, TIME);
  782.     view_to_spline = calc_spline_params(view_to_ctl, TIME);
  783.     light_pos_spline = calc_spline_params(light_pos_ctl, TIME);
  784.     logo_pos_spline = calc_spline_params(logo_pos_ctl, TIME);
  785.     logo_rot_spline = calc_spline_params(logo_rot_ctl, TIME);
  786.  
  787.     glutReshapeFunc(resize_window);
  788.     glutDisplayFunc(display);
  789.     glutMouseFunc(mouse);
  790.     glutKeyboardFunc(keyboard);
  791.     glutVisibilityFunc(vis);
  792.  
  793.     glMatrixMode(GL_MODELVIEW);
  794. }
  795.  
  796.  
  797. void build_table(void) 
  798. {
  799.     float i, j;
  800.  
  801.     for (j=0.0; j<=TABLERES*1.0; j+=1.0) {
  802.     for (i=0.0; i<=TABLERES*1.0; i+=1.0) {
  803.         table_points[(int)j][(int)i][Z] = (i-TABLERES*1.0/2.0)/2.0;
  804.         table_points[(int)j][(int)i][X] = (j-TABLERES*1.0/2.0)/2.0;
  805.         table_points[(int)j][(int)i][Y] = 0.0;
  806.     }
  807.     }
  808. }
  809.  
  810.  
  811. void draw_table(void)
  812. {
  813.     float c;
  814.     int i, j;
  815.     int k, l;
  816.     float ov[3], lv[3];
  817.  
  818.     glDisable(GL_DEPTH_TEST);
  819.     glDisable(GL_LIGHTING);
  820.  
  821.     ov[X] = light_pos[X]-logo_pos[X];
  822.     ov[Y] = light_pos[Y]-logo_pos[Y];
  823.     ov[Z] = light_pos[Z]-logo_pos[Z];
  824.  
  825.     normalize(ov);
  826.  
  827.     for (j=0; j<=TABLERES; j++) {
  828.       for (i=0; i<=TABLERES; i++) {
  829.     lv[X] = light_pos[X] - table_points[j][i][X];
  830.     lv[Y] = light_pos[Y] - table_points[j][i][Y];
  831.     lv[Z] = light_pos[Z] - table_points[j][i][Z];
  832.     normalize(lv);
  833.     if ((c = dot(lv, ov))<0.0) c = 0.0;
  834.     c = c * c * c * lv[Y] * 255.0;
  835.     /* fade */
  836.     if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  837.       c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  838.     
  839.     tablecolors[j][i] = (int)c;
  840.       }
  841.     }
  842.     
  843.     
  844.     for (l=0; l<TABLERES; l++) {
  845.       
  846.       glBegin(GL_TRIANGLE_STRIP);
  847.       for (k=0; k<=TABLERES; k++) {
  848.     glColor3ub(tablecolors[l][k],
  849.            tablecolors[l][k],
  850.            tablecolors[l][k]);
  851.     glVertex3fv(table_points[l][k]);
  852.  
  853.     glColor3ub(tablecolors[l+1][k],
  854.            tablecolors[l+1][k], 
  855.            tablecolors[l+1][k]);
  856.     glVertex3fv(table_points[l+1][k]);
  857.     
  858.       }
  859.     glEnd();
  860.     }
  861.  
  862.     if (logo_pos[Y]>-0.33 && logo_pos[Y]<0.33) {
  863.     glEnable(GL_DEPTH_TEST);
  864.     }
  865.  
  866.     pca = 0.0;
  867.     glBegin(GL_POLYGON);
  868.     for (i=0; i<4; i++) {
  869.       lv[X] = light_pos[X] - paper_points[i][X];
  870.       lv[Y] = light_pos[Y] - paper_points[i][Y];
  871.       lv[Z] = light_pos[Z] - paper_points[i][Z];
  872.       normalize(lv);
  873.       if ((c = dot(lv, ov))<0.0) c = 0.0;
  874.       c = c * c * c * lv[Y];
  875.       /* fade */
  876.       if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  877.     c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  878.       
  879.       pcr = c * 255; pcg = c * 255; pcb = c * 200;
  880.       pca += c;
  881.       glColor3ub((int)pcr,  (int)pcg,  (int)pcb);
  882.       glVertex3fv(paper_points[i]);
  883.     }
  884.     glEnd();
  885.  
  886.     glPushMatrix();
  887.     glRotatef (0.1 * (-184), 0.0, 1.0, 0.0);
  888.     glTranslatef(-0.3, 0.0, -0.8);
  889.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  890.     glScalef(0.015, 0.015, 0.015);
  891.  
  892.  
  893.     if (current_time>TIME*1.0-5.0) {
  894.     c = (current_time-(TIME*1.0-5.0))/2.0;
  895.     glColor3ub((int)(c*255.0),  (int)(c*255.0),  (int)(c*255.0));
  896.     } else glColor3ub(0,  0,  0);
  897.  
  898.     glDisable(GL_DEPTH_TEST);
  899.  
  900.     draw_i();
  901.     glTranslatef(3.0,  0.0,  0.0);
  902.  
  903.     draw_d();
  904.     glTranslatef(6.0,  0.0,  0.0);
  905.  
  906.     draw_e();
  907.     glTranslatef(5.0,  0.0,  0.0);
  908.  
  909.     draw_a();
  910.     glTranslatef(6.0,  0.0,  0.0);
  911.  
  912.     draw_s();
  913.     glTranslatef(10.0,  0.0,  0.0);
  914.  
  915.     draw_i();
  916.     glTranslatef(3.0,  0.0,  0.0);
  917.  
  918.     draw_n();
  919.     glTranslatef(-31.0,  -13.0,  0.0);
  920.  
  921.     draw_m();
  922.     glTranslatef(10.0,  0.0,  0.0);
  923.  
  924.     draw_o();
  925.     glTranslatef(5.0,  0.0,  0.0);
  926.  
  927.     draw_t();
  928.     glTranslatef(4.0,  0.0,  0.0);
  929.  
  930.     draw_i();
  931.     glTranslatef(3.5,  0.0,  0.0);
  932.  
  933.     draw_o();
  934.     glTranslatef(5.0,  0.0,  0.0);
  935.  
  936.     draw_n();
  937.  
  938.     glPopMatrix();
  939.  
  940. }
  941.  
  942.  
  943.  
  944. void draw_under_table(void) 
  945. {
  946.     int k, l;
  947.  
  948.     if(FALSE) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
  949.  
  950.  
  951.     glColor3ub(0,  0,  0);
  952.  
  953.     for (l=0; l<TABLERES; l++) {
  954.  
  955.     glBegin(GL_TRIANGLE_STRIP);
  956.     for (k=0; k<=TABLERES; k++) {
  957.  
  958.         glVertex3fv(table_points[l][k]);
  959.         glVertex3fv(table_points[l+1][k]);
  960.  
  961.     }
  962.     glEnd();
  963.     }
  964.  
  965.     if(TRUE) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
  966.  
  967. }
  968.  
  969.  
  970.  
  971. void calc_spline(vector v, parameter *params, float current_time)
  972. {
  973.  
  974.     float t;
  975.     int i;
  976.  
  977.     t = current_time - (float)((int)current_time);
  978.  
  979.     for (i=0; i<3; i++) {
  980.  
  981.  
  982.     v[i] = params[(int)current_time][3][i] +
  983.            params[(int)current_time][2][i] * t +
  984.            params[(int)current_time][1][i] * t * t +
  985.            params[(int)current_time][0][i] * t * t * t;
  986.     }
  987.  
  988. }
  989.  
  990.  
  991. parameter *calc_spline_params(vector *ctl_pts, int n)
  992. {
  993.  
  994.     int i, j;
  995.     parameter *params;
  996.  
  997.     if (n<4) {
  998.     fprintf(stderr,
  999.         "calc_spline_params: not enough control points\n");
  1000.     return (NULL);
  1001.     }
  1002.  
  1003.     params = (parameter *)malloc(sizeof(parameter) * (n-3));
  1004.  
  1005.     for (i=0; i<n-3; i++) {
  1006.  
  1007.     for (j=0; j<3; j++) {
  1008.  
  1009.         params[i][3][j] = ctl_pts[i+1][j];
  1010.         params[i][2][j] = ctl_pts[i+2][j] - ctl_pts[i][j];
  1011.         params[i][1][j] =  2.0 * ctl_pts[i][j] +
  1012.                   -2.0 * ctl_pts[i+1][j] +
  1013.                    1.0 * ctl_pts[i+2][j] +
  1014.                   -1.0 * ctl_pts[i+3][j];
  1015.         params[i][0][j] = -1.0 * ctl_pts[i][j] +
  1016.                    1.0 * ctl_pts[i+1][j] +
  1017.                   -1.0 * ctl_pts[i+2][j] +
  1018.                    1.0 * ctl_pts[i+3][j];
  1019.  
  1020.     }
  1021.     }
  1022.  
  1023.     return (params);
  1024. }
  1025.  
  1026.  
  1027. void normalize(vector v)
  1028. {
  1029.     float r;
  1030.  
  1031.     r = sqrt(v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z]);
  1032.  
  1033.     v[X] /= r;
  1034.     v[Y] /= r;
  1035.     v[Z] /= r;
  1036. }
  1037.  
  1038.  
  1039. float dot(vector v1, vector v2)
  1040. {
  1041.     return v1[X]*v2[X]+v1[Y]*v2[Y]+v1[Z]*v2[Z];
  1042. }
  1043.  
  1044.